package com.zyk.scaffold.user.config;

import com.alibaba.cloud.nacos.NacosConfigManager;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.fastjson.JSONValidator;
import com.alibaba.nacos.api.config.listener.Listener;
import com.zyk.scaffold.core.lock.LockComponent;
import com.zyk.scaffold.common.utils.MD5Util;
import com.zyk.scaffold.user.service.FunctionApiService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration;

import java.security.NoSuchAlgorithmException;
import java.util.concurrent.Executor;

@Slf4j
@RefreshScope
@Configuration
public class NacosConfigListenerConfiguration implements InitializingBean {

    @Autowired
    private NacosConfigManager nacosConfigManager;

    @Autowired
    private NacosConfigProperties configProperties;

    @Autowired
    private LockComponent lockComponent;

    @Autowired
    private ObjectProvider<FunctionApiService> functionApiServiceObjectProvider;

    private static final String REDIS_FUNCTION_API_MD5_KEY = "function-api:md5:";

    public static String NACOS_CONFIG_DATAID = "backend-scaffold-function-api";

    @Override
    public void afterPropertiesSet() throws Exception {
        nacosConfigManager.getConfigService().addListener(NACOS_CONFIG_DATAID, configProperties.getGroup(),
                new Listener() {
                    @Override
                    public Executor getExecutor() {
                        return null;
                    }

                    @Override
                    public void receiveConfigInfo(String config) {
                        log.info("nacos public config json:" + config);
                        try {
                            if(StringUtils.isEmpty(config) || JSONValidator.from(config).getType() != JSONValidator.Type.Array){
                                return;
                            }
                            String md5 = null;
                            try {
                                md5 = MD5Util.computeMD5(config);
                            } catch (NoSuchAlgorithmException e) {
                                e.printStackTrace();
                            }
                            if(lockComponent.lock(REDIS_FUNCTION_API_MD5_KEY + md5, md5, 1 << 7)){
                                functionApiServiceObjectProvider.ifAvailable(functionApiService -> {
                                    Boolean b = functionApiService.refreshFunctionApi(config, 0L);
                                    log.info("refresh function api result:{}", b);
                                });
                            }
                        } catch (Exception ex) {
                            log.error("refresh function api error:", ex);
                        }
                    }
                });
    }
}
